#include "discinfo.h"
#include "cfg.h"
#include "client.h"
#include <sqlite3.h>

// ---------------------------------------------
disc_t& disc_t::operator=(const disc_t& other)
// ---------------------------------------------
{
	cddb_id = other.cddb_id;
	disc_id = other.disc_id;
	length  = other.length;
	year    = other.year;
	artist  = other.artist;
	title   = other.title;
	comment = other.comment;
	genre   = other.genre;
	tracks  = other.tracks;
}

// ---------------------------------------------
bool disc_t::save() const
// ---------------------------------------------
{
	std::string sql = Cfg::getPath() + "/db.sqlite3";
  sqlite3* db;
  if (sqlite3_open_v2(sql.data(), &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0) != SQLITE_OK)
  {
    sqlite3_close(db);
    app.getUI()->msg(Ui::ERROR, "DiscInfo") << "Couldn't open disc data database." << Ui::END;
    return false;
  }

  // ensure 'discs' table exists
  sql  = "CREATE TABLE IF NOT EXISTS discs (id TEXT PRIMARY KEY, artist TEXT, title TEXT, year TEXT, comment TEXT, genre TEXT, tracks INTEGER);";
  sql += "DELETE FROM discs WHERE id = '";
  sql += disc_id;
  sql += "'";
  if (sqlite3_exec(db, sql.data(), NULL, NULL, NULL) != SQLITE_OK)
  {
    app.getUI()->msg(Ui::DEBUG, "DiscInfo") << sqlite3_errmsg(db) << Ui::END;
    sqlite3_close(db);
    return false;
  }

  // create the disc's table and empty it
  sql  = "CREATE TABLE IF NOT EXISTS '";
  sql += disc_id;
  sql += "' (track INTEGER PRIMARY KEY, artist TEXT, title TEXT, genre TEXT, comment TEXT);";
  sql += "DELETE FROM '";
  sql += disc_id;
  sql += "'";
  if (sqlite3_exec(db, sql.data(), NULL, NULL, NULL) != SQLITE_OK)
  {
    app.getUI()->msg(Ui::DEBUG, "DiscInfo") << sqlite3_errmsg(db) << Ui::END;
    sqlite3_close(db);
    return false;
  }

  // insert information
  sqlite3_stmt* stmt;
  int state;

  // insert/update disc information
  sql = "INSERT INTO 'discs' VALUES (?, ?, ?, ?, ?, ?, ?)";
  if (sqlite3_prepare_v2(db, sql.data(), sql.size(), &stmt, NULL) != SQLITE_OK)
  {
    app.getUI()->msg(Ui::DEBUG, "DiscInfo") << sqlite3_errmsg(db) << Ui::END;
    sqlite3_finalize(stmt);
    sqlite3_close(db);
    return false;
  }
  sqlite3_bind_text(stmt, 1, disc_id.data(), disc_id.size(), SQLITE_STATIC);
  sqlite3_bind_text(stmt, 2, artist.data(),  artist.size(),  SQLITE_STATIC);
  sqlite3_bind_text(stmt, 3, title.data(),   title.size(),   SQLITE_STATIC);
  sqlite3_bind_text(stmt, 4, year.data(),    year.size(),    SQLITE_STATIC);
  sqlite3_bind_text(stmt, 5, comment.data(), comment.size(), SQLITE_STATIC);
  sqlite3_bind_text(stmt, 6, genre.data(),   genre.size(),   SQLITE_STATIC);
  sqlite3_bind_int (stmt, 7, (int)tracks.size());
  if (sqlite3_step(stmt) != SQLITE_DONE)
  {
    app.getUI()->msg(Ui::DEBUG, "DiscInfo") << sqlite3_errmsg(db) << Ui::END;
    sqlite3_finalize(stmt);
    sqlite3_close(db);
    return false;    
  }
  sqlite3_finalize(stmt);

  // insert/update track information
  sql  = "INSERT INTO '";
  sql += disc_id;
  sql += "' VALUES (?, ?, ?, ?, ?)";
  if (sqlite3_prepare_v2(db, sql.data(), sql.size(), &stmt, NULL) != SQLITE_OK)
  {
    app.getUI()->msg(Ui::DEBUG, "DiscInfo") << sqlite3_errmsg(db) << Ui::END;
    sqlite3_finalize(stmt);
    sqlite3_close(db);
    return false;
  }
  for (int i=0; i<tracks.size(); i++)
  {
    sqlite3_bind_int (stmt, 1, i+1);
    sqlite3_bind_text(stmt, 2, tracks[i].artist.data(),  tracks[i].artist.size(),  SQLITE_STATIC);
    sqlite3_bind_text(stmt, 3, tracks[i].title.data(),   tracks[i].title.size(),   SQLITE_STATIC);
    sqlite3_bind_text(stmt, 4, tracks[i].genre.data(),   tracks[i].genre.size(),   SQLITE_STATIC);
    sqlite3_bind_text(stmt, 5, tracks[i].comment.data(), tracks[i].comment.size(), SQLITE_STATIC);
    if (sqlite3_step(stmt) != SQLITE_DONE)
    {
      app.getUI()->msg(Ui::DEBUG, "DiscInfo") << sqlite3_errmsg(db) << Ui::END;
      sqlite3_finalize(stmt);
      sqlite3_close(db);
      return false;    
    }
    sqlite3_reset(stmt);
  }
  sqlite3_finalize(stmt);

  sqlite3_close(db);
	return true;
}

// ---------------------------------------------
bool disc_t::load()
// ---------------------------------------------
{
	std::string sql = Cfg::getPath() + "/db.sqlite3";
  sqlite3* db;
  if (sqlite3_open_v2(sql.data(), &db, SQLITE_OPEN_READONLY, 0) != SQLITE_OK)
  {
    sqlite3_close(db);
    app.getUI()->msg(Ui::ERROR, "DiscInfo") << "Couldn't open disc data database." << Ui::END;
    return false;
  }
  
  sqlite3_close(db);
	return true;
}
